package org.ifilm.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.ifilm.model.EquipmentOffer;
import org.ifilm.model.EquipmentPosting;
import org.ifilm.model.JobApplication;
import org.ifilm.model.Project;
import org.ifilm.model.UserJobPosting;
import org.ifilm.model.User;
import org.ifilm.service.NoticeService;
import org.ifilm.service.ProjectService;
import org.ifilm.util.GeneralConstants;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * Notice Contoller. All requests about notices will be here
 * @author Mustafa Genç
 *
 */
@Controller
@RequestMapping("/notice/**")
public class NoticeController {
	@Autowired
	private NoticeService noticeService;
	
	@Autowired
	private ProjectService projectService;
	
	@RequestMapping(value = "/createPosting", method = {RequestMethod.POST, RequestMethod.GET})
	public void createPosting(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String requestString = request.getParameter("data");
		
		try {
			JSONObject jsonObject = new JSONObject(requestString);
			
			Long projectId = jsonObject.getLong("projectId");
			Project project = projectService.getProject(projectId);
			
			JSONArray jsonArray = jsonObject.getJSONArray("postingData");
			
			List<UserJobPosting> userJobPostings = new ArrayList<UserJobPosting>();
			List<EquipmentPosting> equipmentPostings = new ArrayList<EquipmentPosting>();
			
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject postingObject = jsonArray.getJSONObject(i);
				
				if (postingObject.getString("post").equals("user")) {
					UserJobPosting userJobPosting = new UserJobPosting();
					userJobPosting.setProject(project);
					userJobPosting.setStatus("open");
					
					String totalNeeded = postingObject.has("number") ? postingObject.getString("number") : null;
					try {
						userJobPosting.setTotalNeeded(Integer.parseInt(totalNeeded));
					} catch (NumberFormatException e) {
						userJobPosting.setTotalNeeded(1);
					}
					
					userJobPosting.setTotalAccepted(0);
					
					String type = postingObject.has("type") ? postingObject.getString("type") : null;
					
					if (StringUtils.isNotBlank(type)) {
						userJobPosting.setType(type);
						
					    userJobPosting.setCreationTime(new Date());
					    userJobPosting.setUpdateTime(new Date());
					
						String roledescription = postingObject.has("roleDesc") ? postingObject.getString("roleDesc") : null;
						if (StringUtils.isNotBlank(roledescription)) {
							
								userJobPosting.setDescription(roledescription);							
						}	
					
						String jobdescription = postingObject.has("jobDesc") ? postingObject.getString("jobDesc") : null;
						if (StringUtils.isNotBlank(jobdescription)) {
							
								userJobPosting.setDescription(jobdescription);							
						}						
						
						String minHeight = postingObject.has("minHeight") ? postingObject.getString("minHeight") : null;
						if (StringUtils.isNotBlank(minHeight)) {
							try {
								userJobPosting.setMinHeight(Integer.parseInt(minHeight));
							} catch (NumberFormatException e) {}
						}
						
						String maxHeight = postingObject.has("maxHeight") ? postingObject.getString("maxHeight") : null;
						if (StringUtils.isNotBlank(maxHeight)) {
							try {
								userJobPosting.setMaxHeight(Integer.parseInt(maxHeight));
							} catch (NumberFormatException e) {}
						}
						
						String minWeight = postingObject.has("minWeight") ? postingObject.getString("minWeight") : null;
						if (StringUtils.isNotBlank(minWeight)) {
							try {
								userJobPosting.setMinWeight(Integer.parseInt(minWeight));
							} catch (NumberFormatException e) {}
						}
						
						String maxWeight = postingObject.has("maxWeight") ? postingObject.getString("maxWeight") : null;
						if (StringUtils.isNotBlank(maxWeight)) {
							try {
								userJobPosting.setMaxWeight(Integer.parseInt(maxWeight));
							} catch (NumberFormatException e) {}
						}
						
						String minAge = postingObject.has("minAge") ? postingObject.getString("minAge") : null;
						if (StringUtils.isNotBlank(minAge)) {
							try {
								userJobPosting.setMinAge(Integer.parseInt(minAge));
							} catch (NumberFormatException e) {}
						}
						
						String maxAge = postingObject.has("maxAge") ? postingObject.getString("maxAge") : null;
						if (StringUtils.isNotBlank(maxAge)) {
							try {
								userJobPosting.setMaxAge(Integer.parseInt(maxAge));
							} catch (NumberFormatException e) {}
						}
						
						String hairColor = postingObject.has("hair") ? postingObject.getString("hair") : null;
						if (StringUtils.isNotBlank(hairColor)) {
							userJobPosting.setHairColor(hairColor);
						}
						
						String eyeColor = postingObject.has("eye") ? postingObject.getString("eye") : null;
						if (StringUtils.isNotBlank(eyeColor)) {
							userJobPosting.setEyeColor(eyeColor);
						}
						
						String gender = postingObject.has("gender") ? postingObject.getString("gender") : null;
						if (StringUtils.isNotBlank(gender)) {
							userJobPosting.setGender(gender);
						}
						
						String physicalDesc = postingObject.has("physicalDesc") ? postingObject.getString("physicalDesc") : null;
						if (StringUtils.isNotBlank(physicalDesc)) {
							userJobPosting.setPhysicalDescription(physicalDesc);
						}
						
						String qualifications = postingObject.has("qualifications") ? postingObject.getString("qualifications") : null;
						if (StringUtils.isNotBlank(qualifications)) {
							userJobPosting.setQualifications(qualifications);
						}
					} else {
						//TODO : ERROR
					}
					
					UserJobPosting createdPosting = noticeService.createJobPosting(userJobPosting);
					
					if (createdPosting != null)	{
						userJobPostings.add(createdPosting);
					}
				} else if (postingObject.getString("post").equals("equipment")) {
					EquipmentPosting equipmentPosting = new EquipmentPosting();
					
					String type = postingObject.has("type") ? postingObject.getString("type") : null;
					
					if (StringUtils.isNotBlank(type)) {
						equipmentPosting.setType(type);
						equipmentPosting.setProject(project);
						equipmentPosting.setStatus("open");
						equipmentPosting.setTotalFound(0);
						
						String totalNeeded = postingObject.has("number") ? postingObject.getString("number") : null;
						try {
							equipmentPosting.setTotalNeeded(Integer.parseInt(totalNeeded));
						} catch (NumberFormatException e) {
							equipmentPosting.setTotalNeeded(1);
						}
						
						String description = postingObject.has("eqpDesc") ? postingObject.getString("eqpDesc") : null;
						if (StringUtils.isNotBlank(description)) {
							equipmentPosting.setDescription(description);
						}
						
						String specifications = postingObject.has("specifications") ? postingObject.getString("specifications") : null;
						if (StringUtils.isNotBlank(specifications)) {
							equipmentPosting.setSpecifications(specifications);
						}
						
						EquipmentPosting createdPosting = noticeService.createEquipmentPosting(equipmentPosting);
						
						if (createdPosting != null)	{
							equipmentPostings.add(createdPosting);
						}
					} else {
						//TODO : error
					}
				}
			}
			
			noticeService.updateProjectPostings(project, userJobPostings, equipmentPostings);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
	
	@RequestMapping(value = "/respondToPosting", method = {RequestMethod.POST, RequestMethod.GET})
	public void respondToPosting(@RequestParam Long jobApplicationId, @RequestParam String responseText, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		JobApplication jobApplication = noticeService.getJobApplicationById(jobApplicationId);
		jobApplication.setId(jobApplicationId);
		
		UserJobPosting jobPosting = jobApplication.getJobposting();
		if (responseText.equalsIgnoreCase(GeneralConstants.APPLY_ACCEPTED)) {
			jobApplication.setStatus(GeneralConstants.APPLY_ACCEPTED);
			jobPosting.setTotalAccepted(jobPosting.getTotalAccepted() + 1);
		} else if (responseText.equalsIgnoreCase(GeneralConstants.APPLY_REJECTED)) {
			jobApplication.setStatus(GeneralConstants.APPLY_REJECTED);
			
		}
		
		jobApplication.setUpdateTime(new Date());
		jobApplication = noticeService.createJobApplication(jobApplication);
	}
	
	@RequestMapping(value = "/listJobPostings", method = {RequestMethod.POST, RequestMethod.GET})
	public ModelAndView listFilms(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ModelAndView result = new ModelAndView("/listJobPostings.jsp");
		
		User loggedUser = getLoggedUser(request);
		
		List<UserJobPosting> postingList = new ArrayList<UserJobPosting>();
		
		if (loggedUser != null) {
			postingList = noticeService.listJobPostings();
		}
		
		result.addObject("postings", postingList);
		
		return result;
	}
	
	@RequestMapping(value = "/applyJob", method = {RequestMethod.POST, RequestMethod.GET})
	public void applyToNotice(@RequestParam Long postingId, HttpServletRequest request, HttpServletResponse response) {
		JobApplication jobApplication = new JobApplication();
		
		User loggedUser = getLoggedUser(request);
		
		if (loggedUser != null) {
			UserJobPosting jobPosting = noticeService.getUserJobPosting(postingId);
			
			if (jobPosting != null) {
				jobApplication.setApplier(loggedUser);
				jobApplication.setJobposting(jobPosting);
				jobApplication.setStatus(GeneralConstants.APPLY_PENDING);//NOT A GOOD WAY
				
				jobApplication.setCreationTime(new Date());
				jobApplication.setUpdateTime(new Date());
				
				jobApplication = noticeService.createJobApplication(jobApplication);
				
				noticeService.updateJobPostingAppliances(jobPosting, jobApplication);
			} else {
				//TODO
			}
		} else {
			//TODO
		}
	}
	
	@RequestMapping(value = "/offerEquipment", method = {RequestMethod.POST, RequestMethod.GET})
	public void offerEquipment(@RequestParam Long postingId, HttpServletRequest request, HttpServletResponse response) {
		EquipmentOffer equipmentOffer = new EquipmentOffer();
		
		User loggedUser = getLoggedUser(request);
		
		if (loggedUser != null) {
			EquipmentPosting equipmentPosting = noticeService.getUserEquipmentPosting(postingId);
			
			if (equipmentPosting != null) {
				equipmentOffer.setOfferer(loggedUser);
				equipmentOffer.setEquipmentPosting(equipmentPosting);
				equipmentOffer.setDescription(equipmentPosting.getDescription());
				equipmentOffer.setStatus(GeneralConstants.APPLY_PENDING);//TOO BAD AGAIN
				
				equipmentOffer.setCreationTime(new Date());
				equipmentOffer.setUpdateTime(new Date());
				
				equipmentOffer = noticeService.createEquipmentOffer(equipmentOffer);
				
				noticeService.updateEquipmentOffers(equipmentPosting, equipmentOffer);
			} else {
				//TODO
			}
		} else {
			//TODO
		}
	}
	
	@RequestMapping(value = "/listAppliersToMyProjects", method = {RequestMethod.POST, RequestMethod.GET})
	public ModelAndView listAppliersToMyProjects(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ModelAndView result = new ModelAndView("/postingAppliers.jsp");
		
		User loggedUser = getLoggedUser(request);
		
		if (loggedUser != null) {
			List<Project> projects = projectService.listUserProjects(loggedUser.getId(), 1, 100);
			result.addObject("projects", projects);
		}
		
		return result;
	}
	
	@RequestMapping(value = "/getApplications", method = {RequestMethod.POST, RequestMethod.GET})
	public ModelAndView getApplications(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ModelAndView result = new ModelAndView("/applianceHistory.jsp");
		
		User loggedUser = getLoggedUser(request);
		
		if (loggedUser != null) {
			List<JobApplication> jobApplications = noticeService.getJobApplications(loggedUser.getId());
			List<EquipmentOffer> equipmentOffers = noticeService.getEquipmentOffers(loggedUser.getId());
			result.addObject("applications", jobApplications);
			result.addObject("offerings",equipmentOffers);
		}
		
		return result;
	}
	
	private User getLoggedUser(HttpServletRequest request) {
		HttpSession session = request.getSession();
		
		return (User) session.getAttribute(GeneralConstants.user);
	}
	
	@RequestMapping(value = "/editPostings", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView editPostings(@RequestParam(value = "projectId") Long projectId, 
	HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		ModelAndView result = new ModelAndView();
		
		Project project = projectService.getProject(projectId);
		
		result.addObject(GeneralConstants.currentProject, project);
		
		result.setViewName("/editPostings.jsp");
	
		return result;
	}
	
	@RequestMapping(value = "/editEachPosting", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView editEachPosting(@RequestParam(value = "postingId") Long postingId, 
	HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		ModelAndView result = new ModelAndView();
		
		UserJobPosting posting = noticeService.getUserJobPosting(postingId);
		
		result.addObject(GeneralConstants.editPosting, posting);
		result.setViewName("/editEachPosting.jsp");
	
		return result;
	}
	
	@RequestMapping(value = "/deleteJobPosting", method = { RequestMethod.POST, RequestMethod.GET })
	public void deleteJobPosting(@RequestParam(value = "postingId") Long postingId, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		UserJobPosting jobPosting = noticeService.getUserJobPosting(postingId);
		
		noticeService.deleteJobPosting(jobPosting);
	}
	
	@RequestMapping(value = "/savePostingEdit", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView savePostingEdit(@RequestParam(value = "postingId") Long postingId, 
	HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		ModelAndView result = new ModelAndView();
		
		UserJobPosting posting = noticeService.getUserJobPosting(postingId);		
							
		if (posting != null) {
			 //TODO
			 String type = posting.getType();
			
			 String description = request.getParameter(GeneralConstants.editPostingDescription);
			 if (StringUtils.isNotBlank(description)) {
					posting.setDescription(description);
			 }
			 
			 String minheight = request.getParameter(GeneralConstants.editPostingMinHeight);
			 if (StringUtils.isNotBlank(minheight)) {
					posting.setMinHeight(Integer.parseInt(minheight));
			 }
			 
			 String maxheight = request.getParameter(GeneralConstants.editPostingMaxHeight);
			 if (StringUtils.isNotBlank(maxheight)) {
					posting.setMaxHeight(Integer.parseInt(maxheight));
			 }
			 
			 String minWeight = request.getParameter(GeneralConstants.editPostingMinWeight);
			 if (StringUtils.isNotBlank(minWeight)) {
					posting.setMinWeight(Integer.parseInt(minWeight));
			 }
			 
			 String maxWeight = request.getParameter(GeneralConstants.editPostingMaxWeight);
			 if (StringUtils.isNotBlank(maxWeight)) {
					posting.setMaxWeight(Integer.parseInt(maxWeight));
			 }
			 
			 String minAge = request.getParameter(GeneralConstants.editPostingMinAge);
			 if (StringUtils.isNotBlank(minAge)) {
					posting.setMinAge(Integer.parseInt(minAge));
			 }
			 
			 String maxAge = request.getParameter(GeneralConstants.editPostingMaxAge);
			 if (StringUtils.isNotBlank(maxAge)) {
					posting.setMaxAge(Integer.parseInt(maxAge));
			 }
			 
			 String hair = request.getParameter(GeneralConstants.editPostingHair);
			 if (StringUtils.isNotBlank(hair)) {
					posting.setHairColor(hair);
			 }
			 
			 String eye = request.getParameter(GeneralConstants.editPostingEye);
			 if (StringUtils.isNotBlank(eye)) {
					posting.setEyeColor(eye);
			 }			 
			 
			 String phydescr = request.getParameter(GeneralConstants.editPostingPhysicalDescription);
			 if (StringUtils.isNotBlank(phydescr)) {
				 posting.setPhysicalDescription(phydescr);
			 }
			 
			 String qualifications = request.getParameter(GeneralConstants.editPostingQualifications);
			 if (StringUtils.isNotBlank(qualifications)) {
				 posting.setQualifications(qualifications);
			 }			 
				 
		}
		
		posting.setUpdateTime(new Date());
		
		//TODO
		noticeService.editJobPosting(posting);	
		
		result.addObject(GeneralConstants.currentProject, posting.getProject());
		result.setViewName("/editPostings.jsp");
		
		return result;				
	}
	
	@RequestMapping(value = "/addPostings", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView addPostings(@RequestParam(value = "projectId") Long projectId, 
	HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//TODO
		ModelAndView result = new ModelAndView();		
		
		Project addProject = projectService.getProject(projectId);
		
		if(addProject != null){
			
			result.addObject("project", addProject);
			
		}
		result.setViewName("/addPostings.jsp");
	
		return result;
	}
}